#include "EyerWASMIndexedDB_PutEvent.hpp"

#include <string.h>
#include <stdlib.h>
#include <emscripten.h>
#include <stdio.h>

extern "C"
{
    EMSCRIPTEN_KEEPALIVE int EyerWASMIndexedDB_PutEvent_Put(
            void * ctx,
            int indexedDBKey,
            const char * key,
            const uint8_t * buf,
            size_t bufSize,
            const char * contentLength,
            const char * rangeLength
            );

    EMSCRIPTEN_KEEPALIVE int EyerWASMIndexedDB_PutEvent_Put_OnSucc(void * ctx)
    {
        Eyer::EyerWASMIndexedDB_PutEvent * event = (Eyer::EyerWASMIndexedDB_PutEvent *)ctx;
        return event->EyerWASMIndexedDB_PutEvent_Put_OnSucc();
    }

    EMSCRIPTEN_KEEPALIVE int EyerWASMIndexedDB_PutEvent_Put_OnFail(void * ctx)
    {
        Eyer::EyerWASMIndexedDB_PutEvent * event = (Eyer::EyerWASMIndexedDB_PutEvent *)ctx;
        return event->EyerWASMIndexedDB_PutEvent_Put_OnFail();
    }
}

namespace Eyer
{
    EyerWASMIndexedDB_PutEvent::EyerWASMIndexedDB_PutEvent(
            int indexedDBKey,
            const std::string & key,
            const uint8_t * buf,
            size_t bufSize,
            int64_t contentLength,
            int64_t rangeLength)
    {
        m_indexedDBKey = indexedDBKey;
        m_key = key;
        m_contentLength = contentLength;
        m_rangeLength = rangeLength;

        if(m_buf != nullptr){
            free(m_buf);
            m_buf =  nullptr;
        }

        m_bufSize = bufSize;
        m_buf = (uint8_t *)malloc(m_bufSize);
        memcpy(m_buf, buf, bufSize);
    }

    EyerWASMIndexedDB_PutEvent::~EyerWASMIndexedDB_PutEvent()
    {
        if(m_buf != nullptr){
            free(m_buf);
            m_buf =  nullptr;
        }
    }

    int EyerWASMIndexedDB_PutEvent::Run()
    {
        std::unique_lock<std::mutex> lck(mtx);

        std::string contentLengthStr = std::to_string(m_contentLength);
        std::string rangeLengthStr = std::to_string(m_rangeLength);

        EyerWASMIndexedDB_PutEvent_Put(
                this,
                m_indexedDBKey,
                m_key.c_str(),
                m_buf,
                m_bufSize,
                contentLengthStr.c_str(),
                rangeLengthStr.c_str());
        return 0;
    }

    int EyerWASMIndexedDB_PutEvent::EyerWASMIndexedDB_PutEvent_Put_OnSucc()
    {
        std::unique_lock<std::mutex> lck(mtx);
        isSucced = true;
        isFinished = true;
        cond.notify_all();
        return 0;
    }

    int EyerWASMIndexedDB_PutEvent::EyerWASMIndexedDB_PutEvent_Put_OnFail()
    {
        std::unique_lock<std::mutex> lck(mtx);
        isSucced = false;
        isFinished = true;
        cond.notify_all();
        return 0;
    }
}